home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / pccp019.zip / XMCRCS.C < prev    next >
Text File  |  1992-05-04  |  7KB  |  359 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12.  
  13. #define DLLSBREG 0
  14. #define DLMSBREG 1
  15. #define INTCTLREG 1
  16. #define INTIDREG 2
  17. #define LCTLREG 3
  18. #define MCTLREG 4
  19. #define STATREG 5
  20. #define MSTATREG 6
  21.  
  22. #define CTSMASK 0x10
  23. #define TXMTMASK 0x20
  24. #define RXRDYMASK 0x01
  25.  
  26. #define INTACK 0x20
  27.  
  28. #define DB7 0x02
  29. #define DB8 0x03
  30. #define STOP2 0x04
  31. #define PARITYEN 0x08
  32. #define PARITYEVEN 0x10
  33. #define DLAB 0x80
  34.  
  35. #define INTBASE1 0x20
  36. #define INTMASK1 0x21
  37. #define INTBASE2 0xa0
  38. #define INTMASK2 0xa1
  39.  
  40. #define TBUFSIZ 256
  41.  
  42. #define NAK 21
  43. #define ACK 6
  44. #define SOH 1
  45. #define EOT 4
  46. #define CAN 24
  47.  
  48. int index, basereg;
  49. unsigned char buf[TBUFSIZ];
  50. unsigned char diffintmask, irqnum;
  51. void (interrupt far *oldvect)();
  52.  
  53. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  54.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  55.     unsigned _es, _ds, _di, _si, _bp, _sp;
  56.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  57.     {
  58.     if(inp(basereg+STATREG)&RXRDYMASK)
  59.         {
  60.         buf[index++]=inp(basereg)&0xff;
  61.         index=index%TBUFSIZ;
  62.         }
  63.     outp(INTBASE1, INTACK);
  64.     outp(INTBASE2, INTACK);
  65.     }
  66.  
  67. sendchar(c)
  68.     unsigned char c;
  69.     {
  70.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
  71.     outp(basereg, c);
  72.     }
  73.  
  74. int follow;
  75.  
  76. int rcharto(ticks)
  77.     int ticks;
  78.     {
  79.     long tstamp, tstamp1, dayofticksp;
  80.     int c;
  81.     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  82.     dayofticksp=0;
  83.     while(1)
  84.         {
  85.         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  86.             dayofticksp+=20*60*60*24;
  87.         if(tstamp1+dayofticksp-tstamp>ticks)
  88.             return(-1); /* NOTE: This is an INT!!! */
  89.         if(follow!=index)
  90.             {
  91.             c=buf[follow++];
  92.             follow=follow%TBUFSIZ;
  93.             return(c);
  94.             }
  95.         }
  96.     }
  97.  
  98. int calccrc(ptr, count)
  99.     char *ptr;
  100.     int count;
  101.     {
  102.     int crc, i;
  103.     crc = 0;
  104.     while(--count >= 0)
  105.         {
  106.         crc = crc ^ (int)*ptr++ << 8;
  107.         for(i = 0; i < 8; ++i)
  108.             if(crc & 0x8000)
  109.                 crc = crc << 1 ^ 0x1021;
  110.             else
  111.                 crc = crc << 1;
  112.         }
  113.     return (crc & 0xFFFF);
  114.     }
  115.  
  116. unsigned char block[128];
  117.  
  118. sblock(blockn)
  119.     int blockn;
  120.     {
  121.     unsigned char c;
  122.     unsigned short crc, rcrc;
  123.     int i;
  124.     crc=calccrc(block, 128);
  125.     sendchar(SOH);
  126.     sendchar(blockn);
  127.     sendchar((blockn^0xff)&0xff);
  128.     for(i=0;i<128;++i)
  129.         sendchar(block[i]);
  130.     sendchar((crc>>8)&0xff);
  131.     sendchar(crc&0xff);
  132.     }
  133.  
  134. unsigned intnum;
  135. unsigned char oldintmask;
  136.  
  137. cleanup()
  138.     {
  139.     if(intnum==10)
  140.         outp(INTMASK2, oldintmask);
  141.     else
  142.         outp(INTMASK1, oldintmask);
  143.     outp(basereg+INTCTLREG, 0x00);
  144.     outp(basereg+MCTLREG, 0x03);
  145.     _dos_setvect(intnum, oldvect);
  146.     }
  147.  
  148. quit()
  149.     {
  150.     cleanup();
  151.     exit(99);
  152.     }
  153.  
  154. main(argc, argv)
  155.     int argc;
  156.     char **argv;
  157.     {
  158.     int i, j, infd, ok, c;
  159.     unsigned char newintmask, lctl, dlmsb, dllsb, blocknum;
  160.     long nbytes;
  161.     unsigned speed;
  162.     int comnum;
  163.     char stopbits;
  164.     index=follow=0;
  165.     lctl=0;
  166.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  167.     printf("xmodem crc send of %s.\n", argv[4]);
  168.     if(argc!=5)
  169.         {
  170.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  171.         exit(1);
  172.         }
  173.     if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
  174.         {
  175.         printf("Error opening file %s.\n", argv[4]);
  176.         exit(2);
  177.         }
  178.     comnum=atoi(argv[1])-1;
  179.     newintmask=0;
  180.     switch(comnum)
  181.         {
  182.         case 0:
  183.             irqnum=4;
  184.             diffintmask=0xff&~0x10;
  185.             basereg=0x3f8;
  186.             break;
  187.         case 1:
  188.             irqnum=3;
  189.             diffintmask=0xff&~0x08;
  190.             basereg=0x2f8;
  191.             break;
  192.         case 2:
  193.             irqnum=4;
  194.             diffintmask=0xff&~0x10;
  195.             basereg=0x3e8;
  196.             break;
  197.         case 3:
  198.             irqnum=3;
  199.             diffintmask=0xff&~0x08;
  200.             basereg=0x2e8;
  201.             break;
  202.         case 4:
  203.             irqnum=2;
  204.             diffintmask=0xff&~0x02;
  205.             basereg=0x3e8;
  206.             break;
  207.         case 5:
  208.             irqnum=2;
  209.             diffintmask=0xff&~0x02;
  210.             basereg=0x2e8;
  211.             break;
  212.         case 6:
  213.             irqnum=5;
  214.             diffintmask=0xff&~0x20;
  215.             basereg=0x3e8;
  216.             break;
  217.         case 7:
  218.             irqnum=5;
  219.             diffintmask=0xff&~0x20;
  220.             basereg=0x2e8;
  221.             break;
  222.         default:
  223.             printf("Bad port choice.\n");
  224.             exit(4);
  225.         }
  226.     intnum=irqnum+8;
  227.     speed=atoi(argv[2]);
  228.     switch(speed)
  229.         {
  230.         case 300:
  231.             dlmsb=0;
  232.             dllsb=0xc0;
  233.             break;
  234.         case 1200:
  235.             dlmsb=0;
  236.             dllsb=0x60;
  237.             break;
  238.         case 2400:
  239.             dlmsb=0;
  240.             dllsb=0x30;
  241.             break;
  242.         case 9600:
  243.             dlmsb=0;
  244.             dllsb=0x0c;
  245.             break;
  246.         case 19200:
  247.             dlmsb=0;
  248.             dllsb=0x06;
  249.             break;
  250.         case 38400:
  251.             dlmsb=0;
  252.             dllsb=0x03;
  253.             break;
  254.         case 57600:
  255.             dlmsb=0;
  256.             dllsb=0x02;
  257.             break;
  258.         default:
  259.             printf("Bad speed.\n");
  260.             exit(5);
  261.         }
  262.     lctl|=DB8;
  263.     stopbits=argv[3][0];
  264.     switch(stopbits)
  265.         {
  266.         case '1':
  267.             break;
  268.         case '2':
  269.             lctl|=STOP2;
  270.             break;
  271.         default:
  272.             printf("Bad stop bits.\n");
  273.             exit(9);
  274.         }
  275.     signal(SIGINT, quit);
  276.     outp(basereg+LCTLREG, DLAB);
  277.     outp(basereg+DLLSBREG, dllsb);
  278.     outp(basereg+DLMSBREG, dlmsb);
  279.     outp(basereg+LCTLREG, lctl);
  280.     oldvect=_dos_getvect(intnum);
  281.     _dos_setvect(intnum, inthndl);
  282.     outp(basereg+INTCTLREG, 0x00);
  283.     outp(basereg+MCTLREG, 0x0b);
  284.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  285.     newintmask=diffintmask;
  286.     newintmask&=oldintmask;
  287.     if(intnum==10)
  288.         outp(INTMASK2, newintmask);
  289.     else
  290.         outp(INTMASK1, newintmask);
  291.     outp(INTBASE1, INTACK);
  292.     outp(INTBASE2, INTACK);
  293.     outp(basereg+INTCTLREG, 0x01);
  294.     outp(INTBASE1, INTACK);
  295.     outp(INTBASE2, INTACK);
  296.     nbytes=0;
  297.     if(rcharto(2000)!='C')
  298.         {
  299.         printf("Spurrious char or no C in 100 seconds.\n");
  300.         cleanup();
  301.         exit(10);
  302.         }
  303.     blocknum=1;
  304.     while(1)
  305.         {
  306.         if((j=read(infd, block, 128))==0)
  307.             {
  308.             printf("\nEnd of file.\n");
  309.             sendchar(EOT);
  310.             do
  311.                 c=rcharto(300);
  312.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  313.             if(c!=ACK)
  314.                 {
  315.                 printf("No ACK of EOT.\n");
  316.                 cleanup();
  317.                 exit(13);
  318.                 }
  319.             else
  320.                 {
  321.                 printf("Successful.\n");
  322.                 cleanup();
  323.                 exit(0);
  324.                 }
  325.             }
  326.         for(c=j;c<128;c++)
  327.             block[c]=26;
  328.         i=0;
  329.         do
  330.             {
  331.             printf("\nSending block %d. ", blocknum);
  332.             sblock(blocknum);
  333.             do
  334.                 c=rcharto(200);
  335.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  336.             }
  337.         while((c==NAK)&&(i++<10));
  338.         if(c!=ACK)
  339.             if(c==NAK)
  340.                 {
  341.                 printf("\nRetry limit exceeded.\n");
  342.                 cleanup();
  343.                 exit(14);
  344.                 }
  345.             else
  346.                 {
  347.                 printf("\nSpurrious character hex %02x; ACK or NAK expected.\n", c);
  348.                 cleanup();
  349.                 exit(11);
  350.                 }
  351.         nbytes+=128;
  352.         printf("Successful. Bytes so far: %ld", nbytes);
  353.         blocknum++;
  354.         }
  355.     printf("Programming error; fell through end; see code.\n");
  356.     cleanup();
  357.     exit(12);
  358.     }
  359.